﻿namespace ImageProcessing.Forms
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Windows.Forms;

    /// <summary>
    /// Resizeform class
    /// </summary>
    public partial class ResizeForm : Form
    {
        #region Singeleton Pattern Methods
        /// <summary>
        /// The one instance of ResizeForm
        /// </summary>
        private static ResizeForm instance = null;

        /// <summary>
        /// Initializes a new instance of the <see cref="ResizeForm"/> class.
        /// </summary>
        protected ResizeForm()
        {
            this.InitializeComponent();
        }

        /// <summary>
        /// Creates an instance of the ApplicationCompanyDB DAL class
        /// </summary>
        /// <returns>Returns a single instance</returns>
        public static ResizeForm GetInstance()
        {
            if (instance == null)
            {
                instance = new ResizeForm();
            }

            return instance;
        }
        #endregion

        /// <summary>
        /// Handles the user request for resizing the opended image.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The EventArgs instance containing the event data.</param>
        private void BtnResize_Click(object sender, EventArgs e)
        {
            if (Main.ImageList.Count == 0)
            {
                MessageBox.Show("Please open an image first.");
                return;
            }

            bool directMapping = true;
            int factorX = 1;
            int factorY = 1;
            try
            {
                if (this.CmbMappingMethod.SelectedIndex == 0)
                {
                    directMapping = true;
                    factorX = factorY = int.Parse(this.TxtboxTargetSize.Text);
                }
                else if (this.CmbMappingMethod.SelectedIndex == 1)
                {
                    directMapping = false;
                    string[] targetSize = this.TxtboxTargetSize.Text.Split('X');
                    factorX = int.Parse(targetSize[0]);
                    factorY = int.Parse(targetSize[1]);
                }
            }
            catch (Exception ex)
            {
                Logger.LogException(ex);
                MessageBox.Show("Refill the target size correctly.\n" + ex.ToString());
            }

            int resizeAlgo = this.CmbResizingAlgo.SelectedIndex;
            switch (resizeAlgo)
            {
                // 0-order (by repeating pixels) //direct mapping by factor
                case 0:
                    Main.OperationName = "Resize nearest neighbor to: " + factorX + " X " + factorY;
                    Main.ImageList[Main.CurrImage].UpdateImage(ResizeImage.NearestNeighborResize(Main.ImageList[Main.CurrImage].ImageBitmap, false, factorX, factorY));
                    break;

                // Bilinear
                case 1:
                    Main.OperationName = "Resize Billinear to: " + factorX + " X " + factorY;
                    //((PictureBox)Main.Instance.MainTabContainer.tempPanel.Controls[0]).Image = ResizeImage.BiLineResize(factorX, factorY, Main.ImageList[Main.CurrImage].ImageBitmap);
                    Main.ImageList[Main.CurrImage].UpdateImage(ResizeImage.BiLineResize(factorX, factorY, Main.ImageList[Main.CurrImage].ImageBitmap));
                    break;

                // Bi-cubic
                case 2:
                    Main.OperationName = "Resize Bicubic to: " + factorX + " X " + factorY;
                    Main.ImageList[Main.CurrImage].UpdateImage(ResizeImage.BicubicResize(factorX, factorY, Main.ImageList[Main.CurrImage].ImageBitmap, this.CmbInterpolationMode.SelectedIndex));
                    break;

                // S-Spline
                case 3:
                    break;
            }
        }

        /// <summary>
        /// Validate resizing data.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The CancelEventArgs instance containing the event data.</param>
        private void PnlResize_Validating(object sender, CancelEventArgs e)
        {
            if (this.TxtboxTargetSize.Text == string.Empty)
            {
                MessageBox.Show("target resizing size is emty please set");
                return;
            }
            else
            {
                Regex targetSizeValidator;

                if (this.CmbMappingMethod.SelectedIndex == 0)
                {
                    targetSizeValidator = new Regex(@"\d");
                }
                else if (this.CmbMappingMethod.SelectedIndex == 1)
                {
                    targetSizeValidator = new Regex(@"\dX\d");
                }
                else
                {
                    MessageBox.Show("Select mapping method for resizing.");
                    return;
                }

                if (!targetSizeValidator.IsMatch(this.TxtboxTargetSize.Text))
                {
                    MessageBox.Show("Target size format is not valid either enter \"digit\" or \"digitXdigit\" ");
                    return;
                }
            }
        }

        /// <summary>
        /// Handles the SelectedIndexChanged event of the CmbResizingAlgo control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void CmbResizingAlgo_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.CmbResizingAlgo.SelectedIndex == 2)
            {
                this.CmbInterpolationMode.Enabled = true;
            }
            else
            {
                this.CmbInterpolationMode.Enabled = false;
            }
        }
    }
}
